package com.frp.client;

import com.frp.protocol.Message;
import com.frp.protocol.MessageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 心跳管理器
 * 负责维护与FRP服务器的心跳连接
 */
public class HeartbeatManager {
    private static final Logger logger = LoggerFactory.getLogger(HeartbeatManager.class);
    
    private final ConnectionManager connectionManager;
    private final int heartbeatInterval;
    private final int heartbeatTimeout;
    private final AtomicBoolean running = new AtomicBoolean(false);
    private Thread heartbeatThread;
    
    public HeartbeatManager(ConnectionManager connectionManager, int heartbeatInterval, int heartbeatTimeout) {
        this.connectionManager = connectionManager;
        this.heartbeatInterval = heartbeatInterval;
        this.heartbeatTimeout = heartbeatTimeout;
    }
    
    /**
     * 启动心跳管理器
     */
    public void start() {
        if (running.compareAndSet(false, true)) {
            logger.info("启动心跳管理器，间隔: {}秒", heartbeatInterval);
            
            heartbeatThread = new Thread(this::heartbeatLoop, "Heartbeat-Manager");
            heartbeatThread.setDaemon(true);
            heartbeatThread.start();
        }
    }
    
    /**
     * 停止心跳管理器
     */
    public void stop() {
        if (running.compareAndSet(true, false)) {
            logger.info("停止心跳管理器");
            
            if (heartbeatThread != null) {
                heartbeatThread.interrupt();
            }
        }
    }
    
    /**
     * 心跳循环
     */
    private void heartbeatLoop() {
        long lastHeartbeatTime = System.currentTimeMillis();
        
        while (running.get() && connectionManager.isRunning()) {
            try {
                // 发送心跳
                Message heartbeat = new Message(MessageType.Heartbeat);
                connectionManager.sendMessage(heartbeat);
                
                lastHeartbeatTime = System.currentTimeMillis();
                logger.debug("发送心跳包");
                
                // 等待下一个心跳
                Thread.sleep(heartbeatInterval * 1000L);
                
                // 检查心跳超时
                long currentTime = System.currentTimeMillis();
                if (currentTime - lastHeartbeatTime > heartbeatTimeout * 1000L) {
                    logger.warn("心跳超时，尝试重新连接...");
                    // 连接管理器会处理重连
                    break;
                }
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            } catch (IOException e) {
                logger.error("发送心跳失败", e);
                try {
                    Thread.sleep(5000);  // 等待5秒后重试
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }
        
        logger.info("心跳管理器已停止");
    }
    
    /**
     * 检查是否正在运行
     */
    public boolean isRunning() {
        return running.get();
    }
}